package besta.moon.sql.expression.function.string;

import besta.moon.sql.expression.function.FunctionReturnP1StringAndBinary;
import besta.moon.sql.parser.SQLTokenizer;

public class FunctionSoundex extends FunctionReturnP1StringAndBinary {

    @Override
    public final int getFunction() {
        return SQLTokenizer.SOUNDEX;
    }

    @Override
    public final boolean isNull() throws Exception {
        return param1.isNull();
    }

    @Override
    public final byte[] getBytes() throws Exception {
        throw createUnspportedConversion(SQLTokenizer.BINARY);
    }

    @Override
    public final String getString() throws Exception {
        if (isNull()) {
            return null;
        }
        String input = param1.getString();
        return getString(input);
    }

    static String getString(String input) {
        char[] output = new char[4];
        int idx = 0;
        input = input.toUpperCase();
        if (input.length() > 0) {
            output[idx++] = input.charAt(0);
        }
        char last = '0';
        for (int i = 1; idx < 4 && i < input.length(); i++) {
            char c = input.charAt(i);
            c = switch (c) {
                case 'B', 'F', 'P', 'V' -> '1';
                case 'C', 'G', 'J', 'K', 'Q', 'S', 'X', 'Z' -> '2';
                case 'D', 'T' -> '3';
                case 'L' -> '4';
                case 'M', 'N' -> '5';
                case 'R' -> '6';
                default -> '0';
            };
            if (c > '0' && last != c) {
                output[idx++] = c;
            }
            last = c;
        }
        for (; idx < 4;) {
            output[idx++] = '0';

        }
        return new String(output);
    }

    @Override
    public int getPrecision() {
        return 4;
    }
}
